﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace IMPL.Controls
{
    class ImagePanel
    {
        private readonly Brush selectedBackgroundBrush;
        private readonly Brush defaultBackgroundBrush;
        private readonly int histogramPanelWidth = 400;

        public DockPanel MainPanel { get; set; }
        public DockPanel ContainingPanel { get; set; }
        private DockPanel HistogramPanel { get; set; }

        private bool IsSidePanelVisible;

        public ImagePanel(BitmapSource bitmap)
        {
            //set default colors
            selectedBackgroundBrush = SystemColors.ControlDarkBrush;
            defaultBackgroundBrush = SystemColors.ControlBrush;

            IsSidePanelVisible = false;

            MainPanel = new DockPanel();
            MainPanel.Background = this.defaultBackgroundBrush;

            InitGrip();

            InitSidePanel();

            var image = new Image();
            image.Source = bitmap;
            image.Name = "Image";
            MainPanel.LastChildFill = true;
            MainPanel.Children.Add(image);

            MainPanel.MinHeight = 30;
            MainPanel.MinWidth = 10;
            MainPanel.Width = bitmap.Width;
            MainPanel.Height = bitmap.Height;

            MainPanel.Focusable = true;

            ContainingPanel = new DockPanel();
            DockPanel.SetDock(MainPanel, Dock.Left);
            ContainingPanel.Children.Add(MainPanel);

            HistogramPanel = new DockPanel();
            HistogramPanel.Background = SystemColors.DesktopBrush;
            DockPanel.SetDock(HistogramPanel, Dock.Right);
            HistogramPanel.Width = 0;
            ContainingPanel.Children.Add(HistogramPanel);

            InitHistogram();
        }

        private void InitGrip()
        {
            var grip = new ResizeGrip();
            grip.MouseDown += grip_MouseDown;
            grip.MouseUp += grip_MouseUp;
            grip.MouseMove += grip_MouseMove;

            DockPanel.SetDock(grip, Dock.Bottom);
            MainPanel.Children.Add(grip);
        }

        private void InitSidePanelButton()
        {
            var sidePanelButton = new Button();
            sidePanelButton.Click += sidePanelButton_Click;
            sidePanelButton.Width = 20;
            sidePanelButton.Content = ">";

            DockPanel.SetDock(sidePanelButton, Dock.Right);
            MainPanel.Children.Add(sidePanelButton);
        }

        private void InitHistogram()
        {
            // Create a drawing of two ellipses.
            GeometryDrawing aDrawing = new GeometryDrawing();

            // Use geometries to describe two overlapping ellipses.
            EllipseGeometry ellipse1 = new EllipseGeometry();
            ellipse1.RadiusX = 20;
            ellipse1.RadiusY = 45;
            ellipse1.Center = new Point(50, 50);
            EllipseGeometry ellipse2 = new EllipseGeometry();
            ellipse2.RadiusX = 45;
            ellipse2.RadiusY = 20;
            ellipse2.Center = new Point(50, 50);
            GeometryGroup ellipses = new GeometryGroup();
            ellipses.Children.Add(ellipse1);
            ellipses.Children.Add(ellipse2);

            // Add the geometry to the drawing.
            aDrawing.Geometry = ellipses;

            // Specify the drawing's fill.
            aDrawing.Brush = Brushes.Blue;

            // Specify the drawing's stroke.
            Pen stroke = new Pen();
            stroke.Thickness = 10.0;
            stroke.Brush = new LinearGradientBrush(
                Colors.Black, Colors.Gray, new Point(0, 0), new Point(1, 1));
            aDrawing.Pen = stroke;

            // Create a DrawingBrush
            DrawingBrush myDrawingBrush = new DrawingBrush();
            myDrawingBrush.Drawing = aDrawing;

            // Create a Rectangle element.
            Rectangle aRectangle = new Rectangle();
            aRectangle.Width = 150;
            aRectangle.Height = 150;
            aRectangle.Stroke = Brushes.Black;
            aRectangle.StrokeThickness = 1.0;

            // Use the DrawingBrush to paint the rectangle's 
            // background.
            aRectangle.Fill = myDrawingBrush;

            HistogramPanel.Children.Add(aRectangle);
        }

        private void InitSidePanel()
        {
            InitSidePanelButton();
        }

        void sidePanelButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.IsSidePanelVisible)
            {
                HistogramPanel.Width = 0;
                ((Button)sender).Content = '>';
                this.IsSidePanelVisible = false;
            }
            else
            {
                HistogramPanel.Width = this.histogramPanelWidth;
                ((Button)sender).Content = '<';
                this.IsSidePanelVisible = true;
            }
        }

        public void SetMouseDown(MouseButtonEventHandler handler)
        {
            this.MainPanel.MouseDown += handler;
        }

        private bool selected = false;
        public bool Selected
        {
            get
            {
                return selected;
            }
            set
            {
                if (value)
                {
                    this.MainPanel.Background = this.selectedBackgroundBrush;
                    this.MainPanel.Focus();
                }
                else
                {
                    this.MainPanel.Background = this.defaultBackgroundBrush;
                }
            }
        }

        private bool isResizing = false;
        private Point startPoint;

        private void grip_MouseMove(object sender, MouseEventArgs e)
        {
            if (isResizing)
            {
                var grip = (ResizeGrip)sender;
                var imagePanel = (DockPanel)grip.Parent;
                Point newPt = e.GetPosition(grip);

                var newWidth = imagePanel.Width + newPt.X - startPoint.X;
                var newHeight = imagePanel.Height + newPt.Y - startPoint.Y;

                if (newWidth > 10)
                    imagePanel.Width = newWidth;
                if (newHeight > 10)
                    imagePanel.Height = newHeight;

                this.startPoint = newPt;
            }
        }

        void grip_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                var grip = (ResizeGrip)sender;

                Mouse.Capture(grip);
                startPoint = e.GetPosition(grip);
                isResizing = true;
            }
        }

        void grip_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (isResizing)
            {
                var grip = (ResizeGrip)sender;
                var imagePanel = (DockPanel)grip.Parent;
                Point newPt = e.GetPosition(grip);
                imagePanel.Width += newPt.X - startPoint.X;
                imagePanel.Height += newPt.Y - startPoint.Y;
                isResizing = false;
                grip.ReleaseMouseCapture();
            }
        }
    }
}
